package com.corgi.test.encrypt;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @title: AESDemo
 * @description:
 * @author: dengmiao
 * @create: 2019-10-30 14:16
 **/
public class AESDemo {

    /**
     * 初始向量 AES为16bytes
     */
    public static final String INIT_KEY="1122334455667788";

    /**
     * 编码方式
     */
    public static final String UTF8 = "UTF-8";

    /**
     * 秘钥 AES固定格式为128/192/256 bits.即：16/24/32bytes。
     */
    private static final String AES_KEY = "1122334455667788";

    /**
      * 加密
      * @param 需要加密的字符串
      * 加密方式:AES128(CBC/PKCS5Padding)+Base64
      */
    public static String encrypt(String encryptText){
        try {
            IvParameterSpec parameterSpec = new IvParameterSpec(INIT_KEY.getBytes());
            //第一个参数为：秘钥字节数组 ，第二个参数为加密方式AES
            SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(),"AES");
            //实例化加密类，参数为加密方式,PKCS5Padding比PKCS7Padding效率高，PKSC7Padding可支持IOS加密
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //初始化,此方法可以有三种方式，(1)无第三个参数（2）SecureRandom random = new SecureRandom();random对象为随机数，AES不可取（3）使用IvParameterSpec
            //第一个参数表明是加密ENCRYPT_MODE
            cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
            //执行加密操作，加密后的数据为字节数组
            byte[] encryptedData = cipher.doFinal(encryptText.getBytes(UTF8));
            //使用BASE64Encoder把字节数组转成字符串
            String result = new BASE64Encoder().encode(encryptedData);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
      * 解密
      * @param 加密后的的字符串
      */
    public static String decrypt(String decryptText){
        try {
            //使用BASE64Decoder().decodeBuffer把字符串转成字节数组
            byte[] encryptByte = new BASE64Decoder().decodeBuffer(decryptText);
            IvParameterSpec parameterSpec = new IvParameterSpec(INIT_KEY.getBytes());
            SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(),"AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key,parameterSpec);
            byte[] decryptedData = cipher.doFinal(encryptByte);
            String result = new String(decryptedData,UTF8);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        String encryptText = "我喜欢你";
        System.out.println("加密前文本："+encryptText);
        String encryptResult = AESDemo.encrypt(encryptText);
        System.out.println("加密后文本："+encryptResult);
        String decryptResult = AESDemo.decrypt(encryptResult);
        System.out.println("解密后的文本："+decryptResult);
    }
}
